package com.jdb.loan.controller;

import com.guns21.jackjson.annotation.JsonMixin;
import com.guns21.jackjson.annotation.JsonResponse;
import com.guns21.jackjson.mixins.ResultMixin;
import com.guns21.result.domain.PageResult;
import com.guns21.result.domain.Result;
import com.guns21.support.controller.BaseController;
import com.guns21.support.util.WebUtils;
import com.guns21.web.bind.annotation.RequireUuid;
import com.guns21.web.constant.SpringConstant;
import com.jdb.loan.api.Constants;
import com.jdb.loan.api.dto.LoanCategoryDTO;
import com.jdb.loan.api.dto.LoanDTO;
import com.jdb.loan.api.query.AmountCondition;
import com.jdb.loan.api.query.LoanQuery;
import com.jdb.loan.api.service.FavoriteService;
import com.jdb.loan.controller.assembler.LoanAssembler;
import com.jdb.loan.controller.assembler.LoanCategoryAssmbler;
import com.jdb.loan.controller.mixins.AmountConditionMixin;
import com.jdb.loan.controller.mixins.LoanCategoryDTOMixin;
import com.jdb.loan.controller.mixins.LoanDTOMixin;
import com.jdb.loan.provider.entity.LoanDO;
import com.jdb.loan.provider.service.AmountConditionService;
import com.jdb.loan.provider.service.LoanCommandService;
import com.jdb.loan.provider.service.LoanQueryService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.util.Date;

/**
 * @author jliu
 */
@RestController
@RequestMapping("/api/loan/v1")
public class LoanController extends BaseController {

    @Autowired
    private LoanCommandService loanCommandService;
    @Autowired
    private LoanQueryService loanQueryService;

    @Autowired
    private FavoriteService favoriteService;

    @Autowired
    private AmountConditionService amountConditionService;

    /**
     * @param time
     * @param forward
     * @param count
     * @param amountConditionId
     * @param categoryId
     * @return
     */
    @GetMapping("/list")
    @JsonResponse(mixins = {@JsonMixin(target = PageResult.class, mixin = ResultMixin.class),
            @JsonMixin(target = LoanDTO.class, mixin = LoanDTOMixin.class)})
    public PageResult<LoanDTO> list(@RequestParam(required = false) Date time,
                                    @RequestParam(defaultValue = "true", required = false) Boolean forward,
                                    @RequestParam(defaultValue = "20", required = false) Integer count,
                                    @RequestParam(required = false) String amountConditionId,
                                    @RequestParam(required = false) String categoryId) {

        AmountCondition amountCondition = Constants.QUERY_ALL.equalsIgnoreCase(amountConditionId) ? null : amountConditionService.getAmountCondition(amountConditionId);

        return loanQueryService.list(time, forward, count,
                amountCondition,
                Constants.QUERY_ALL.equalsIgnoreCase(categoryId) ? null : categoryId);
    }

    @GetMapping(value = "/detail/{id:" + SpringConstant.UUID_REGEX_32 + "}")
    public Result detail(@PathVariable String id,
                         @RequireUuid(required = false) String userId) {

        Result<LoanDTO> loanDTOResult = loanQueryService.get(id);
        if (StringUtils.isNoneEmpty(userId) && loanDTOResult.getSuccess()) {
            Result result = favoriteService.get(id);
            if (result.getSuccess()) {
                loanDTOResult.getData().setCollection(result.getData() != null);
                loanDTOResult.getData().setCover(WebUtils.buildWebUrlWithFile(loanDTOResult.getData().getCover()));
            }
        }

        return loanDTOResult;
    }


    /**
     * 贷款分类列表
     *
     * @return
     */
    @GetMapping("/categories")
    @JsonResponse(mixins = {@JsonMixin(target = PageResult.class, mixin = ResultMixin.class),
            @JsonMixin(target = LoanCategoryDTO.class, mixin = LoanCategoryDTOMixin.class)})
    public PageResult<LoanCategoryDTO> categories() {
        PageResult<LoanCategoryDTO> loanCategoryDTOPageResult = loanQueryService.listCategories();
        LoanCategoryDTO loanCategoryDTO = new LoanCategoryDTO();
        loanCategoryDTO.setName(Constants.QUERY_ALL_TEXT);
        loanCategoryDTO.setId(Constants.QUERY_ALL);
        loanCategoryDTOPageResult.getData().add(0, loanCategoryDTO);
        return loanCategoryDTOPageResult;
    }

    /**
     * 返回金额查询条件
     *
     * @return
     */
    @GetMapping("/condition/amounts")
    @JsonResponse(mixins = {@JsonMixin(target = PageResult.class, mixin = ResultMixin.class),
            @JsonMixin(target = AmountCondition.class, mixin = AmountConditionMixin.class)})
    public PageResult<AmountCondition> amounts() {

        return PageResult.success(amountConditionService.listAmountConditions());
    }

    /**
     * 收藏列表
     *
     * @param time
     * @param forward
     * @param count
     * @param userId
     * @return
     */
    @GetMapping("/favorites")
    public PageResult favorites(@RequestParam(required = false) Date time,
                                @RequestParam(defaultValue = "true", required = false) Boolean forward,
                                @RequestParam(defaultValue = "20", required = false) Integer count,
                                @RequireUuid(required = false) String userId) {
        PageResult<String> result = favoriteService.listId(userId, time, forward, count);
        if (result.getSuccess()) {
            return loanQueryService.list(result.getData());
        } else {
            return result;
        }
    }

    // --------------------------------------------------------------
    @PostMapping("/save")
    public Result<LoanDTO> save(@RequestBody LoanDTO loanDTO) {
        LoanDO loanDO = LoanAssembler.fromDTO(loanDTO);
        return loanCommandService.save(loanDO);
    }

    @PostMapping("/category/save")
    public Result<LoanCategoryDTO> saveCategory(@RequestBody LoanCategoryDTO loanCategoryDTO) {
        return loanCommandService.saveCategory(LoanCategoryAssmbler.fromDTO(loanCategoryDTO));
    }

    @GetMapping("/listByPage")
    public PageResult listByPage(LoanQuery loanQuery) {

        return loanQueryService.listByPage(loanQuery);
    }

    @GetMapping(value = "/detailAll/{id:" + SpringConstant.UUID_REGEX_32 + "}")
    public Result detailAll(@PathVariable String id) {
        return loanQueryService.get(id);
    }
}
